
#include "BlazeStdAfx.h"
#include "BlazeMaxExport.h"
#include "BlazeMaxExportDesc.h"

UtilityObj* CExporter::m_pBlazeMain = NULL;
CExporter* CExporter::m_pThis = NULL;
Interface* CExporter::m_pMax = NULL;

extern HINSTANCE g_hInstance;

static void ModifyCallback(void* param, NotifyInfo* info)
{
	switch(info->intcode)
	{
	case NOTIFY_SYSTEM_POST_NEW:
	case NOTIFY_FILE_POST_MERGE:
	case NOTIFY_FILE_POST_OPEN:
	case NOTIFY_POST_IMPORT:
	case NOTIFY_SYSTEM_POST_RESET:
	case NOTIFY_FILE_OPEN_FAILED:
	case NOTIFY_IMPORT_FAILED:
		((CExporter*)param)->LoadConfig();
		break;
	}
}

CExporter::CExporter(CExporterDesc* pDesc)
{
	m_pMax = NULL;
	m_pMaxUtil = NULL;
	m_hPanel = NULL;
	m_pThis = this;

	RegisterNotification(ModifyCallback, this, NOTIFY_SYSTEM_POST_RESET);
	RegisterNotification(ModifyCallback, this, NOTIFY_SYSTEM_POST_NEW);
	RegisterNotification(ModifyCallback, this, NOTIFY_FILE_POST_OPEN);
	RegisterNotification(ModifyCallback, this, NOTIFY_FILE_POST_MERGE);
	RegisterNotification(ModifyCallback, this, NOTIFY_POST_IMPORT);
	RegisterNotification(ModifyCallback, this, NOTIFY_FILE_OPEN_FAILED);
	RegisterNotification(ModifyCallback, this, NOTIFY_IMPORT_FAILED);
}

CExporter::~CExporter()
{
	UnRegisterNotification(ModifyCallback, this, NOTIFY_SYSTEM_POST_RESET);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_SYSTEM_POST_NEW);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_FILE_POST_OPEN);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_FILE_POST_MERGE);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_POST_IMPORT);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_FILE_OPEN_FAILED);
	UnRegisterNotification(ModifyCallback, this, NOTIFY_IMPORT_FAILED);

	m_pThis = NULL;


}

void CExporter::BeginEditParams(Interface* ip, IUtil* iu)
{
	if(m_pBlazeMain==NULL)
	{
		m_pBlazeMain = this;

		m_pMax = ip;
		m_pMaxUtil = iu;

		m_hPanel = ip->AddRollupPage(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_CONFIG), ConfigDlgProc, BLAZE_EXPORTER_TITLE, 0);
	}
}

void CExporter::EndEditParams(Interface* ip, IUtil* iu)
{	
	if(m_pBlazeMain==NULL)
		return;

	m_pBlazeMain = NULL;

	ip->DeleteRollupPage(m_hPanel);
	m_hPanel = NULL;

}

void CExporter::DeleteThis()
{
	delete this;
}

INT_PTR CALLBACK CExporter::ConfigDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch(Msg)
	{
	case WM_INITDIALOG:
		break;

	case WM_DESTROY:
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDC_PROPERTIES_BUTTON:
			m_pThis->OnPanelButtonProperties();
			break;

		case IDC_EXPORT_BUTTON:
			m_pThis->OnPanelButtonExport();
			break;

			//case IDC_CLOSE_BUTTON:
			//	m_pThis->m_pMaxUtil->CloseUtility();
			//	return 0; // do not process further

		case IDOK:
		case IDCANCEL:
			break;
		}
		break;

	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_MOUSEMOVE:
		m_pThis->m_pMax->RollupMouseMessage(hWnd, Msg, wParam, lParam); 
		break;

	default:
		return FALSE;
	}

	return TRUE;
}

void CExporter::LoadConfig()
{

}

void CExporter::SaveConfig()
{

}

void CExporter::OnPanelButtonProperties()
{

}

typedef unsigned char uint8;
typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
typedef int int32;

/*#pragma pack(push,1)*/

struct ModelHeader {
	char id[4];
	uint8 version[4];
	uint32 nameLength;
	uint32 nameOfs;
	uint32 type;

	uint32 nGlobalSequences;
	uint32 ofsGlobalSequences;
	uint32 nAnimations;
	uint32 ofsAnimations;
	uint32 nC;
	uint32 ofsC;
	uint32 nD;
	uint32 ofsD;
	uint32 nBones;
	uint32 ofsBones;
	uint32 nF;
	uint32 ofsF;

	uint32 nVertices;
	uint32 ofsVertices;
	uint32 nViews;
	uint32 ofsViews;

	uint32 nColors;
	uint32 ofsColors;

	uint32 nTextures;
	uint32 ofsTextures;

	uint32 nTransparency; // H
	uint32 ofsTransparency;
	uint32 nI;   // always unused ?
	uint32 ofsI;
	uint32 nTexAnims;	// J
	uint32 ofsTexAnims;
	uint32 nK;
	uint32 ofsK;

	uint32 nTexFlags;
	uint32 ofsTexFlags;
	uint32 nY;
	uint32 ofsY;

	uint32 nTexLookup;
	uint32 ofsTexLookup;

	uint32 nTexUnitLookup;		// L
	uint32 ofsTexUnitLookup;
	uint32 nTransparencyLookup; // M
	uint32 ofsTransparencyLookup;
	uint32 nTexAnimLookup;
	uint32 ofsTexAnimLookup;

	float floats[14];

	uint32 nBoundingTriangles;
	uint32 ofsBoundingTriangles;
	uint32 nBoundingVertices;
	uint32 ofsBoundingVertices;
	uint32 nBoundingNormals;
	uint32 ofsBoundingNormals;

	uint32 nO;
	uint32 ofsO;
	uint32 nP;
	uint32 ofsP;
	uint32 nQ;
	uint32 ofsQ;
	uint32 nLights; // R
	uint32 ofsLights;
	uint32 nCameras; // S
	uint32 ofsCameras;
	uint32 nT;
	uint32 ofsT;
	uint32 nRibbonEmitters; // U
	uint32 ofsRibbonEmitters;
	uint32 nParticleEmitters; // V
	uint32 ofsParticleEmitters;

};


const char* GetNameFromID(unsigned int iID)
{
	if(iID == 0) return "<SceneRoot>";

	INode* pNode = GetNodeFromID(iID);
	return pNode ? pNode->GetName() : "<invalid>";
}

static INode* GetNodeFromID(unsigned int iID, INode* pNode)
{
	if(pNode->GetHandle() == iID)
		return pNode;

	unsigned int iNumChildren = pNode->NumberOfChildren();
	for(unsigned int i = 0; i < iNumChildren; i++)
	{
		INode* pSubNode = GetNodeFromID(iID, pNode->GetChildNode(i));
		if(pSubNode) 
			return pSubNode;
	}

	return NULL;
}

INode* GetNodeFromID(unsigned int iID)
{
	return GetNodeFromID(iID, CExporter::GetMax()->GetRootNode());
}

SClass_ID GetClassIDFromNodeID(unsigned int iID)
{
	INode* pNode = GetNodeFromID(iID);
	return pNode ? GetClassIDFromNode(pNode) : NULL;
}

SClass_ID GetClassIDFromNode(INode* pNode)
{
	const ObjectState& os = pNode->EvalWorldState(0, TRUE);
	return os.obj ? os.obj->SuperClassID() : NULL;
}

void CExporter::Build()
{
	int iCount = 0;
	
	INode* pRootNode = m_pThis->m_pMax->GetRootNode();
// 	
	if (pRootNode != NULL)
 	{
 		iCount = pRootNode->NumberOfChildren();
// 		
 		for(int i=0;i<iCount;i++)
 		{
 			INode* pNode = pRootNode->GetChildNode(i);
 			if(pNode==NULL || pNode->IsNodeHidden())
 				continue;
 
 			MessageBox(NULL, pNode->GetName(), "root", 0);

	
 		} 	
 	}
// 	else
/*	{
		iCount = m_pThis->m_pMax->GetSelNodeCount();
	
		for(int i=0;i<iCount;i++)
		{
			INode* pNode = m_pThis->m_pMax->GetSelNode(i);
			if(pNode==NULL || pNode->IsNodeHidden())
				continue;

			MessageBox(NULL, pNode->GetName(), "", 0);
		}
	}
	*/

}


void CExporter::OnPanelButtonExport()
{
	Build();
	
}
